/**
 *  @file
 *  @brief   T形（T）梁截面属性使用数值方法计算类
 *  @author  hongjiaqi
 *  @date    2024.07.19
 *  @version v1.0
 *  @par Copyright(c):  ShenGong  Simulation corporation
 */
#include "TSectionNumericalCalculator.h"

#include "DataStructure/Common/Real.h"

#include "SectionCalculator/StandardSectionTool.h"

using SG::Algebra::Point;
using SG::DataStructure::Common::Real;
using SG::DataStructure::FEM::PBARLData;
using SG::FEMSolver::Element::TSectionNumericalCalculator;

void TSectionNumericalCalculator::Mesh (const PBARLData& section, _OUT Meshes& meshes, int refineLevel) const
{
    Real w{ section.m_dimension[0] };
    Real h{ section.m_dimension[1] };
    Real tf{ section.m_dimension[2] };
    Real tw{ section.m_dimension[3] };
    Real bf{ 0.5 * (w - tw) };
    Real hw{ h - tf };

    int n   = refineLevel + 1;
    int ntf = n;
    int ntw = n;
    int nbf = n;
    int nhw = 2 * n;

    StandardSectionTool secMesh;
    Point               point;
    int                 nodeId{ 0 };
    int                 eleId{ 0 };
    Meshes              newMeshes;
    NodeSet             newEdgeNodes;
    int                 numRepeatNodes{ 0 };
    NodeSet             edgeNodes;

    // 1st block
    point.m_y = -bf;
    point.m_z = hw;
    secMesh.MeshRect (point, bf, tf, nbf, ntf, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);

    // 2nd block
    point.m_y = tw;
    secMesh.MeshRect (point, -tw, tf, ntw, ntf, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    numRepeatNodes = 2 * ntf + 1;
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);

    // 3rd block
    point.m_y = tw + bf;
    secMesh.MeshRect (point, -bf, tf, nbf, ntf, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    numRepeatNodes = 2 * ntf + 1;
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);

    // 4th block
    point.m_y = 0.0;
    point.m_z = 0.0;
    secMesh.MeshRect2 (point, tw, hw, ntw, nhw, nodeId, eleId, _OUT newMeshes, _OUT newEdgeNodes);
    numRepeatNodes = 2 * ntw + 1;
    secMesh.Merge (edgeNodes, numRepeatNodes, newMeshes, meshes, nodeId, eleId);
    secMesh.UpdateEdgeNodes (newEdgeNodes, numRepeatNodes, edgeNodes);
}